﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace libReadWrite
{
    public abstract class BigEndianReader
    {
        public short ReadInt16()
        {
            return BitConverter.ToInt16(ReadBigEndianBytes(2), 0);
        }

        public ushort ReadUInt16()
        {
            return BitConverter.ToUInt16(ReadBigEndianBytes(2), 0);
        }

        public uint ReadUInt32()
        {
            return BitConverter.ToUInt32(ReadBigEndianBytes(4), 0);
        }

        public int ReadInt32()
        {
            return BitConverter.ToInt32(ReadBigEndianBytes(4), 0);
        }

        public ulong ReadULong()
        {
            return BitConverter.ToUInt64(ReadBigEndianBytes(8), 0);
        }

        public long ReadLong()
        {
            return BitConverter.ToInt64(ReadBigEndianBytes(8), 0);
        }

        public double ReadDouble()
        {
            return BitConverter.ToDouble(ReadBigEndianBytes(8), 0);
        }

        public void Skip(int length)
        {
            ReadBytes(length);
        }

        public abstract byte[] ReadBigEndianBytes(int count);

        public abstract byte ReadByte();

        public abstract byte[] ReadBytes(int count);

        public string ReadString()
        {
            
            int n = ReadInt32();

            if (n != 0)
            {
                byte[] buffer = ReadBytes(n);

                String str = System.Text.Encoding.Unicode.GetString(buffer);

                return str;
            }
            else
            {
                return "";
            }
        }

        public byte[] ReadByteArray()
        {

            int n = ReadInt32();

            if (n > 0)
            {
                byte[] buffer = ReadBytes(n);

                return buffer;
            }
            else {
                throw new IOException();
            }
        }

        public abstract void Close();
    }
}
